<%
'--------------------------------------------------------------------
'系统内置函数，不懂的不要乱做修改，否则可能影响整个程序系统。
'--------------------------------------------------------------------

Sub Echo(ByVal s)
	AB.C.Print s
End Sub

Sub Print(ByVal s)
	AB.C.Print s
End Sub

Function IntVal(ByVal n)
	On Error Resume Next
	If AB.C.IsNum(n) Then
		IntVal = CLng(n)
	Else
		IntVal = 0
	End If
	On Error Goto 0
End Function

Function isNul(ByVal s)
	isNul = AB.C.IsNul(s)
End Function

Function isBlank(ByVal s)
	isBlank = AB.C.IsNul(s)
End Function

Function isNone(ByVal s)
	isNone = AB.C.isNone(s)
End Function

'短化日期(月-日)
Function sDate(ByVal t)
	sDate = ""
	If Not (AB.C.IsNul(t) Or Trim(t)="") then
		sDate = AB.C.DateTime(Cdate(t),"mm-dd")
	End If
End Function

'标准化日期格式
Function StdDate(ByVal t)
	StdDate = ""
	If Not (AB.C.IsNul(t) Or Trim(t)="") then
		StdDate = AB.C.DateTime(Cdate(t),"yyyy-mm-dd")
	End If
End Function

'短化时间格式
Function ShortTime(ByVal t)
	ShortTime = ""
	If Not (AB.C.IsNul(t) Or Trim(t)="") then
		ShortTime = AB.C.DateTime(Cdate(t),"yyyy-mm-dd hh:ii")
	End If
End Function

'标准化时间格式
Function StdTime(ByVal t)
	StdTime = ""
	If Not (AB.C.IsNul(t) Or Trim(t)="") then
		StdTime = AB.C.DateTime(Cdate(t),"yyyy-mm-dd hh:ii:ss")
	End If
End Function

'Form表单转为字典集
Function dictForm()
	On Error Resume Next
	Dim d, i, f, v, spl : Set d = AB.C.Dict()
	AB.Use "Form"
	'AB.Form.Fun = "AB.E.UnEscape" '设置Form函数
	spl = "<hr class=""ke-pagebreak"" style=""page-break-after:always;"" />" '分页分隔符
	For i=0 To AB.Form.Count-1
		f = AB.Form(i).Name
		v = AB.Form(i).Value
		If LCase(f)="content" Then
			v = AB.C.RP(v, spl, "[page]")
		End If
		d(f) = v
	Next
	Set dictForm = d
	On Error Goto 0
End Function

'获取URL参数值
Function Req(ByVal s)
	Req = App.Req(s)
End Function

'获取URL参数值。若值为空，则值为指定值
Function ReqSet(ByVal p, ByVal s)
	ReqSet = App.ReqSet(p, s)
End Function

'基本等同于ReqSet，区别在于值强制转化为整型
Function ReqInt(ByVal p, ByVal s)
	ReqInt = App.ReqInt(p, s)
End Function

Public Function FixAbsPath(ByVal p)
	p = AB.C.IIF(Left(p,1)= "/", p, "/" & p)
	p = AB.C.IIF(Right(p,1)="/", p, p & "/")
	FixAbsPath = p
End Function

Function toJson(ByVal str, ByVal n, ByVal msg)
	If Trim(n)="" Then n = 1
	msg = Trim(msg)
	AB.Use "Json"
	str = AB.Json.toJson(str)
	str = AB.C.RP(str, Array("\\","\'",Chr(0)), Array(Chr(0),"'","\\")) '兼容火狐
	toJson = "{""status"":"& n &",""msg"":"""& msg &""",""data"":" & str & ",""dialog"":""""}"
End Function

Function dataReturn(ByVal status, ByVal msg, ByVal data, ByVal dialog, ByVal [type])
	Dim str, d : Set d = AB.C.Dict()
	d("status") = status : d("msg") = msg : d.Add "data", data : d.Add "dialog", dialog
	If LCase([type])="json" Or Trim([type])="" Or Trim([type])="0" Then
		AB.Use "Json"
		str = AB.Json.toJson(d)
	ElseIf LCase([type])="xml" Then
		AB.Use "Xml" : Dim Xml : Set Xml = AB.Xml.New
		'Xml.Load "<?xml version=""1.0"" encoding=""utf-8""?><root></root>"
		Xml.RootDom("root")
		Xml("root")(0).Append(Xml.Create("status", status))
		Xml("root")(0).Append(Xml.Create("msg", msg))
		Xml("root")(0).Append(Xml.Create("data", data))
		Xml("root")(0).Append(Xml.Create("dialog", dialog))
		str = Xml.Dom.Xml
		Set Xml = Nothing
	Else
		str = data
	End If
	dataReturn = str
End Function

'系列化数据，成功返回字符串
'e.g.
' dim jso : set jso = ab.json.jsEval("{firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'}")
' ab.trace serialize(jso)
Function serialize(ByVal p)
	Dim jsLib, jso, j : serialize = Empty
	AB.Use "jsLib"
	Set jsLib = AB.jsLib.New : jsLib.Inc("serialize.js")
	Set jso = jsLib.Object
	If IsObject(jso.serialize(p)) Then Set serialize = jso.serialize(p) Else serialize = jso.serialize(p)
	Set jso = Nothing
	Set jsLib = Nothing
End Function

'反系列化数据，成功返回一个JScript对象
'e.g.
' dim jso : set jso = ab.json.jsEval("{firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'}")
' ab.trace unserialize( serialize(jso) )
' ab.trace unserialize("a:3:{i:0;s:5:""Kevin"";i:1;s:3:""van"";i:2;s:9:""Zonneveld"";}")
Function unserialize(ByVal p)
	Dim jsLib, jso, j : unserialize = Empty
	AB.Use "jsLib"
	Set jsLib = AB.jsLib.New : jsLib.Inc("serialize.js")
	Set jso = jsLib.Object
	Set j = jso.unserialize(p)
	If Not ( Err.Number<>0 Or AB.C.IsNul(j) ) Then
		Set unserialize = j
	End If
	Set jso = Nothing
	Set jsLib = Nothing
End Function

'获取网站项目所在URL地址(绝对地址)
Function RootURL()
	RootURL = App.RootURL()
End Function

'获取网站所在目录，在根路径返回空值
Function ROOT()
	ROOT = App.RootPath()
End Function

'本页面绝对地址，并带有页面Hash参数
Function FullURL()
	FullURL = AB.C.GetUrl("")
End Function

'当前页相对地址，且带页面参数
Function URL()
	URL = AB.C.GetUrl(1)
End Function

'当前页相对地址，且不带页面参数
Function SELF()
	SELF = AB.C.GetUrl(0)
End Function

Function ajaxReturn(ByVal status, ByVal msg)
	On Error Resume Next
	If status="" Then status = 1
	status = CInt(status)
	App.Out.Put dataReturn(status, msg, "", "", "")
	App.Exit()
	On Error Goto 0
End Function

Sub DisplayTpl(ByVal tpl, ByVal p)
	On Error Resume Next
	If p=1 Then
		App.Out.Put toJson(App.View.GetTplHtml(tpl),1,"")
	Else
		App.View.Display(tpl)
	End If
	On Error Goto 0
End Sub

'警告提示(不跳转)
Sub Alert(ByVal message)
	On Error Resume Next
	Dim msgTitle : msgTitle = "提示信息"
	App.View.LayerOut = False
	App.View.Assign "message", message
	App.View.Assign "msgTitle", msgTitle
	App.View.Display(App.View.Path_Theme & "/common/error.html")
	App.Exit()
	On Error Goto 0
End Sub

'警告提示，跳转
Sub warnTip(ByVal message, ByVal jumpUrl, ByVal msgTitle, ByVal waitSecond)
	On Error Resume Next
	If Trim(jumpUrl)="-1" Then
		jumpUrl = "history.back(-1)"
	ElseIf Trim(jumpUrl)="0" Or jumpUrl="" Then
		jumpUrl = "location.reload()"
	Else
		jumpUrl = "location.href='"& jumpUrl &"'"
	End If
	If msgTitle="" Then msgTitle = "操作失败！"
	If Not AB.C.IsNum(waitSecond) Then waitSecond = 3
	waitSecond = CLng(waitSecond)
	If waitSecond<=0 Then waitSecond = 3
	App.View.LayerOut = False
	App.View.Assign "message", message
	App.View.Assign "jumpUrl", jumpUrl
	App.View.Assign "msgTitle", msgTitle
	App.View.Assign "waitSecond", waitSecond
	App.View.Display(App.View.Path_Theme & "/common/message.html")
	App.Exit()
	On Error Goto 0
End Sub

'出错提示，跳转
Sub errTip(ByVal message, ByVal jumpUrl, ByVal msgTitle, ByVal waitSecond)
	On Error Resume Next
	If Trim(jumpUrl)="-1" Then
		jumpUrl = "history.back(-1)"
	ElseIf Trim(jumpUrl)="0" Or jumpUrl="" Then
		jumpUrl = "location.reload()"
	Else
		jumpUrl = "location.href='"& jumpUrl &"'"
	End If
	If msgTitle="" Then msgTitle = "操作失败！"
	If Not AB.C.IsNum(waitSecond) Then waitSecond = 3
	waitSecond = CLng(waitSecond)
	If waitSecond<=0 Then waitSecond = 3
	App.View.LayerOut = False
	App.View.Assign "message", message
	App.View.Assign "jumpUrl", jumpUrl
	App.View.Assign "msgTitle", msgTitle
	App.View.Assign "waitSecond", waitSecond
	App.View.Display(App.View.Path_Theme & "/common/error.html")
	App.Exit()
	On Error Goto 0
End Sub

'成功提示，跳转
Sub winTip(ByVal message, ByVal jumpUrl, ByVal msgTitle, ByVal waitSecond)
	On Error Resume Next
	If Trim(jumpUrl)="-1" Then
		jumpUrl = "history.back(-1)"
	ElseIf Trim(jumpUrl)="0" Or jumpUrl="" Then
		jumpUrl = "location.reload()"
	Else
		jumpUrl = "location.href='"& jumpUrl &"'"
	End If
	If msgTitle="" Then msgTitle = "操作成功！"
	If Not AB.C.IsNum(waitSecond) Then waitSecond = 3
	waitSecond = CLng(waitSecond)
	If waitSecond<=0 Then waitSecond = 3
	App.View.LayerOut = False
	App.View.Assign "message", message
	App.View.Assign "jumpUrl", jumpUrl
	App.View.Assign "msgTitle", msgTitle
	App.View.Assign "waitSecond", waitSecond
	App.View.Display(App.View.Path_Theme & "/common/success.html")
	App.Exit()
	On Error Goto 0
End Sub

'提示信息
Sub msgTip(ByVal message)
	On Error Resume Next
	App.View.LayerOut = False
	App.View.Assign "message", message
	App.View.Assign "msgTitle", "提示："
	App.View.Display(App.View.Path_Theme & "/common/message.html")
	On Error Goto 0
End Sub

Sub AlertGo(ByVal msg, ByVal url)
	Dim go
	If Trim(url)="-1" Then
		go = "history.back();"
	ElseIf Trim(url)="0" Or Trim(url)="" Then
		go = "location.reload();"
	Else
		go = "this.location.href='"& url &"';"
	End If
	AB.C.Put ("<script language=javascript>alert('"& msg &"');"& go &"</script>")
End Sub

'替换变量值
Function RpVar(ByVal str)
	Dim Matches, Match
	If AB.C.RegTest(str, "\{\$?(\w+)\}") Then '含变量
		Set Matches = AB.C.RegMatch(str, "\{\$?(\w+)\}")
		For Each Match In Matches
			str = AB.C.RP( str, Match.Value, Eval(Match.SubMatches(0)) )
		Next
		Set Matches = Nothing
	End If
	RpVar = str
End Function

'获取完整数据表名
Function Table(ByVal p)
	Table = App.Dao.tbPrefix & p
End Function
Function GetTable(ByVal p)
	GetTable = Table(p)
End Function

'调用Widget单元组件执行函数
'e.g. W("advert/index",1)
Function W(ByVal m, ByVal param)
	On Error Resume Next
	Dim tmp, path, unit, func, widget
	unit = AB.C.CLeft(m,"/")
	func = AB.C.CRight(m,"/")
	If func = "" Then func = "index"
	path = App.LibPath() & "Widget/" & unit & "Widget.class.asp"
	App.ReadFile path
	Set Widget = New advertWidget
	If Err.Number=0 Then
		If Not AB.C.isNul(param) Then '带参数
			Execute("tmp = Widget."& func &"(param)")
		Else '不带参数
			Execute("tmp = Widget."& func &"()")
			If Err.Number<>0 Then
				Err.Clear
				Execute("tmp = Widget."& func &"(param)")
			End If
		End If
	End If
	W = tmp
	On Error Goto 0
End Function

'ACTION定向函数（支持路由定向）
' 例，有以下书写形式：
' F("index")
' F("index/index")
' F("admin/index/index")
' F("admin:index/index?id=100")
' F("index.asp?m=admin&c=index&a=index&id=100")
Sub F(ByVal p)
	On Error Resume Next
	Dim m, c, a, url, t, q, arr, qs, qc, qv : url = U(p) : Set qs = AB.C.Dict()
	Dim bs_m, bs_c, bs_a, self : self = "index.asp"
	bs_m = AB.C.IIF(REQ_M<>"",REQ_M,"home")
	bs_c = AB.C.IIF(REQ_C<>"",REQ_C,"index")
	bs_a = AB.C.IIF(REQ_A<>"",REQ_A,"index")
	self = AB.C.RP(self, ".", "\.")
	t = Right(url, Len(url) - InstrRev(url,"/"))
	If AB.C.RegTest(t, self &"\??(.*)") Then
		If Instr(t,"?")>0 Then
			q = AB.C.CRight(t, "?")
			For Each d In Split(q, "&")
				qc = Trim(AB.C.CLeft(d,"="))
				qv = AB.C.CRight(d,"=")
				qs(LCase(qc)) = qv
			Next
			For Each d In qs
				App.SetReq Trim(d), qs(d)
			Next
		End If
		m = AB.C.IIF(Trim(qs("m"))="", bs_m, Trim(qs("m")))
		c = AB.C.IIF(Trim(qs("c"))="", bs_c, Trim(qs("c")))
		a = AB.C.IIF(Trim(qs("a"))="", bs_a, Trim(qs("a")))
		App.SetReq "m", m
		App.SetReq "c", c
		App.SetReq "a", a
	End If
	App.RunA a, c &":"& m
	App.Exit()
	On Error Goto 0
End Sub

'URL跳转（支持路由跳转）
'a. 直接书写地址 R("index.asp?m=user&c=index&a=run&id=100")
'b. URL模式 R("user/index/run/?id=100")
Sub R(ByVal p)
	App.RR p
End Sub

'URL组装
Function U(ByVal p)
	On Error Resume Next
	Dim Matches, Match, m, c, a, t, url, rules(5), dictQs
	Dim self : self = AB.C.IIF(App.Default_Document()<>"", App.Default_Document(), "index.asp")
	If Not App.Display_Document() Then self = "" '是否显示默认文档
	Dim tmp, k, v, default_group : default_group = App.Default_Group
	rules(0) = "^(\w+)[\:\/](\w+)\/(\w+)\??(.*)$"
	rules(1) = "^(\w+)\/(\w+)\??(.*)$"
	rules(2) = "^(\w+)\??(.*)$"
	If AB.C.RegTest(p, rules(0)) Then
		Set Matches = AB.C.RegMatch(p, rules(0))
		For Each Match In Matches
			m = Trim(Match.SubMatches(0))
			c = Trim(Match.SubMatches(1))
			a = Trim(Match.SubMatches(2))
			t = Trim(Match.SubMatches(3))
		Next
		url = ""& self & "?m=" & m & "&c=" & c & "&a=" & a & AB.C.IIF(t="", t, "&" & t)
		If LCase(m) = LCase(default_group) Then url = AB.C.RP(url, "?m=" & m & "&", "?")
		If LCase(c) = "index" Then url = AB.C.RegReplace(url, "([\?&])c=index[&]*", "$1")
		If LCase(a) = "index" Then url = AB.C.RegReplace(url, "([\?&])a=index[&]*", "$1")
		If Right(url,1)="?" Or Right(url,1)="&" Then url = Left(url,Len(url)-1)
	ElseIf AB.C.RegTest(p, rules(1)) Then
		m = REQ_M
		Set Matches = AB.C.RegMatch(p, rules(1))
		For Each Match In Matches
			c = Trim(Match.SubMatches(0))
			a = Trim(Match.SubMatches(1))
			t = Trim(Match.SubMatches(2))
		Next
		url = ""& self & "?m=" & m & "&c=" & c & "&a=" & a & AB.C.IIF(t="", t, "&" & t)
		If LCase(m) = LCase(default_group) Then url = AB.C.RP(url, "?m=" & m & "&", "?")
		If LCase(c) = "index" Then url = AB.C.RegReplace(url, "([\?&])c=index[&]*", "$1")
		If LCase(a) = "index" Then url = AB.C.RegReplace(url, "([\?&])a=index[&]*", "$1")
		If Right(url,1)="?" Or Right(url,1)="&" Then url = Left(url,Len(url)-1)
	ElseIf AB.C.RegTest(p, rules(2)) Then
		m = REQ_M : c = REQ_C
		Set Matches = AB.C.RegMatch(p, rules(2))
		For Each Match In Matches
			a = Trim(Match.SubMatches(0))
			t = Trim(Match.SubMatches(1))
		Next
		url = ""& self & "?m=" & m & "&c=" & c & "&a=" & a & AB.C.IIF(t="", t, "&" & t)
		If LCase(m) = LCase(default_group) Then url = AB.C.RP(url, "?m=" & m & "&", "?")
		If LCase(c) = "index" Then url = AB.C.RegReplace(url, "([\?&])c=index[&]*", "$1")
		If LCase(a) = "index" Then url = AB.C.RegReplace(url, "([\?&])a=index[&]*", "$1")
		If Right(url,1)="?" Or Right(url,1)="&" Then url = Left(url,Len(url)-1)
	Else
		url = p
		tmp = Split(AB.C.CRight(url,"?"), "&")
		Set dictQs = AB.C.Dict()
		For Each qs In tmp
			k = AB.C.CLeft(qs,"=")
			v = AB.C.CRight(qs,"=")
			If Not dictQs.Exists(LCase(k)) Then dictQs(LCase(k)) = v Else dictQs(LCase(k)) = dictQs(LCase(k)) & ", " & v
		Next
		For Each k In dictQs
			v = dictQs(k)
			If LCase(k) = "m" And LCase(v) = LCase(default_group) Then
				dictQs.Remove(k)
			End If
			If LCase(k) = "c" And LCase(v) = "index" Then
				dictQs.Remove(k)
			End If
			If LCase(k) = "a" And LCase(v) = "index" Then
				dictQs.Remove(k)
			End If
		Next
		t = ""
		For Each k In dictQs
			t = t & "&" & k & "=" & dictQs(k)
		Next
		If Left(t,1)="&" Then t = AB.C.CRight(t,"&")
		url = ""& self & AB.C.IIF(t="", "", "?"& t)
		Set dictQs = Nothing
	End If
	Set Matches = Nothing
	If Left(url,1)<>"/" Then
		url = ROOT() & "/" & url
	End If
	U = url
	On Error Goto 0
End Function

'读取App配置信息
Function C(ByVal p)
	If IsObject(App.CfgVal(p)) Then
		Set C = App.CfgVal(p)
	Else
		C = App.CfgVal(p)
	End If
End Function

'语言函数, 若当前节点含有子节点，则返回一个字典对象（含子节点键名和子节点值）
Function L(ByVal p)
	On Error Resume Next
	Dim str, dict, o, t, a, i, j, k, langDir : langDir = App.LangPath
	Dim f : f = "zh-cn.xml" '语言配置文件
	f = langDir & AB.C.IIF(REQ_M="", f, REQ_M & "/" & f)
	AB.Use "A"
	If AB.C.isFile(f) Then
		AB.Use "Xml" : Dim Xml : Set Xml = AB.Xml.New
		Xml.Load f
		a = Array() : a = AB.A.Push(a, "config")
		If Instr(p,"/")>0 Or Instr(p,">")>0 Then
			p = Replace(p,"/",">")
			k = Split(p,">")
			For i=0 To UBound(k)
				If Trim(k(i))<>"" Then a = AB.A.Push(a, Trim(k(i)))
			Next
		Else
			a = AB.A.Push(a, p)
		End If
		a = AB.A.Clean(a)
		If IsArray(a) And Not AB.C.isNul(a) Then p = Join(a,">") Else p = ""
		If Xml(p).Length>1 Then '含有子节点
			Set dict = AB.C.Dict()
			For i=0 To Xml(p)(0).Length-1
				If Xml(p)(0).Child(i).IsNode Then
					If Xml(p)(0).Child(i).Length>1 Then '再包含子节点
						Set t = Xml(p)(0).Child(i)
						Set o = AB.C.Dict()
						For j=0 To t(0).Length-1
							If t(0).Child(j).IsNode Then
								name = t(0).Child(j).Name
								text = t(0).Child(j).Text
								text = RpVar(text) '替换含变量
								o(name) = text
							End If
						Next
						Set dict(t.Name) = o
						Set o = Nothing
						Set t = Nothing
					ElseIf Xml(p)(0).Child(i).Length=1 Then
						name = Xml(p)(0).Child(i).Name
						text = Xml(p)(0).Child(i).Text
						text = RpVar(text) '替换含变量
						dict(name) = text
					End If
				End If
			Next
			Set str = dict
		ElseIf Xml(p).Length=1 Then '不含子节点
			str = Xml(p)(0).Text
			str = RpVar(str) '替换含变量
		End If
	End If
	If IsObject(str) Then Set L = str Else L = str
	On Error Goto 0
End Function

'创建模型函数
'e.g.
'Dim User : Set User = M("User")
''User.Table = "User"
'Dim Rs : Set Rs = User().Find(1).Result()

Function M(ByVal p)
	On Error Resume Next
	If Err Then Err.Clear()
	Dim t, e, j, tmp, arr, als, tb
	p = Trim(p)
	If AB.C.IsNul(p) Then
		Set M = App.Model.New
		Exit Function
	End If
	If Instr(p," ")>0 Then
		als = Trim(AB.C.CRight(p," "))
		p = Trim(AB.C.CLeft(p," "))
	End If
	If App.Dao.db.tbExists(Table(p)) Then '数据表存在才能创建模型
		''屏蔽缓存效果
		' e = LCase("App_Model_" & p & "")
		' If AB.FnHas(e) And IsObject(AB.FnItem(e)) Then
			' Set M = AB.FnItem(e)
		' Else
			' Execute("Set M = New Model_"& AB.D.MCase(p) &" : M.Table = """ & LCase(p) & """")
			' If Err Then
				' Err.Clear()
				' Set M = App.Model.New
				' M.Table = LCase(p)
			' End If
			' AB.FnAdd e, M
		' End If
		't = AB.D.MCase(Lcase(p))
		arr = Array()
		tmp = Split(p,"_")
		For j=0 To UBound(tmp)
			arr = AB.A.Push(arr, AB.D.MCase(LCase(tmp(j))))
		Next
		t = Join(arr,"_")
		tb = LCase(p)
		If als<>"" Then tb = tb & " " & als
		Execute("Set M = New Model_"& t &" : M.Table = """ & tb & """")
		If Err Then
			Err.Clear()
			Set M = App.Model.New
			M.Table = tb
		End If
	Else
		Set M = Nothing
	End If
	If Err Then Set M = Nothing
	On Error Goto 0
End Function

'-------------- 仍需完善 ----------------

'格式化输出值：
'%s - 字符串
'%d - 十进制数(整型)
'%f - 浮点数
'%c - 依照 ASCII 值的字符
'%o - 八进制数
'%x - 十六进制数（小写字母）
'%X - 十六进制数（大写字母）

Function Sprintf(ByVal format, ByVal t)
	Dim Matches, Match, rule, m, val, i, str : str = format : i = 0
	AB.Use "Char"
	rule = "%(s|d|f|c|o|x|X)"
	Set Matches = AB.C.RegMatch(str, rule)
	For Each Match In Matches
		m = Match.SubMatches(0)
		Select Case m
			Case "s" : val = CStr(t)
			Case "d" : val = CLng(t)
			Case "f" : val = CDbl(t)
			Case "c" : val = AB.C.AscII(t)
			Case "o" : val = t
			Case "x" : val = LCase(AB.Char.C10To2(AB.Char.C2To16(t))) '进制: 10->16（小写字母）
			Case "X" : val = UCase(AB.Char.C10To2(AB.Char.C2To16(t))) '进制: 10->16（大写字母）
		End Select
		str = AB.C.RP(str, Match.Value, val)
		i = i+1
	Next
	Set Matches = Nothing
	Sprintf = str
End Function

%>